Analise Exploratória de Dados com Python#
Emendas Paralamentares#
Iremos analisar os dados de Emendas Parlamentares distribuídas nos anos de 2023 e 2024. NOsso foco será são nos dados do estado do Ceará e seus municípios. Estes dados estão disponíveis no Painel de Emendas Paralamentares do Portal da Transparência.
Importando as bibliotecas necessárias:
numpy: coleção de funções matemáticas
pandas: biblioteca para manipulação e análise de dados
matplotlib: criação de gráficos e visualização de dados
plotly: gráficos interativos
babel: deixar valores monetário em moeda nacional
import numpy as np
import pandas as pd
import matplotlib.pylab as plt
import plotly.io as pio
import plotly.express as px
import plotly.offline as py
from babel.numbers import format_currency
# retirar notação científica do pandas
# pd.set_option('display.float_format', '{:.2f}'.format)
Os dados foram baixados em formato csv e estão na raiz do projeto.
# carregando os dados
df = pd.read_csv('../emendas.csv', sep=';')
# exibindo as primeiras 3 linhas
df.head(3)
| Ano | Tipo de Emenda | Autor da emenda | Número da emenda | Localidade do gasto (Regionalização) | Função | Subfunção | Programa Orçamentário | Ação Orçamentária | Plano Orçamentário | Código da emenda | Valor empenhado | Valor liquidado | Valor pago | Valor Restos a Pagar Inscritos | Valor Restos a Pagar Cancelados | Valor Restos a Pagar Pagos | Unnamed: 17 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2022 | Emenda Individual - Transferências Especiais | MARCIO ALVINO | 6 | SÃO PAULO (UF) | Encargos especiais | Outras transferências | 0903 - OPERACOES ESPECIAIS: TRANSFERENCIAS CON... | 0EC2 - TRANSFERENCIAS ESPECIAIS | TRANSFERENCIAS ESPECIAIS | 202237170006 | 100.000,00 | 0,00 | 0,00 | 100.000,00 | 0,00 | 100.000,00 | NaN |
| 1 | 2024 | Emenda Individual - Transferências Especiais | JUNIO AMARAL | 16 | MINAS GERAIS (UF) | Encargos especiais | Outras transferências | 0903 - OPERACOES ESPECIAIS: TRANSFERENCIAS CON... | 0EC2 - TRANSFERENCIAS ESPECIAIS | TRANSFERENCIAS ESPECIAIS | 202439240016 | 100.000,00 | 0,00 | 0,00 | 0,00 | 0,00 | 0,00 | NaN |
| 2 | 2024 | Emenda Individual - Transferências Especiais | JOAQUIM PASSARINHO | 14 | PARÁ (UF) | Encargos especiais | Outras transferências | 0903 - OPERACOES ESPECIAIS: TRANSFERENCIAS CON... | 0EC2 - TRANSFERENCIAS ESPECIAIS | TRANSFERENCIAS ESPECIAIS | 202436920014 | 100.000,00 | 100.000,00 | 100.000,00 | 0,00 | 0,00 | 0,00 | NaN |
Estrutura#
É importante sabermos a estrutura do nosso Dataframe (quantidade de linhas e colunas, quais os tipos de dados) para posteriormente selecionarmos as colunas de nosso interesse e realizamos alguma conversão de tipo de dado. Essa estrutura pode ser exibida da seguinte forma:
# informações sobre a base
df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 2849 entries, 0 to 2848
Data columns (total 18 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 Ano 2849 non-null int64
1 Tipo de Emenda 2849 non-null object
2 Autor da emenda 2849 non-null object
3 Número da emenda 2849 non-null int64
4 Localidade do gasto (Regionalização) 2849 non-null object
5 Função 2849 non-null object
6 Subfunção 2849 non-null object
7 Programa Orçamentário 2849 non-null object
8 Ação Orçamentária 2849 non-null object
9 Plano Orçamentário 2849 non-null object
10 Código da emenda 2849 non-null int64
11 Valor empenhado 2849 non-null object
12 Valor liquidado 2849 non-null object
13 Valor pago 2849 non-null object
14 Valor Restos a Pagar Inscritos 2849 non-null object
15 Valor Restos a Pagar Cancelados 2849 non-null object
16 Valor Restos a Pagar Pagos 2849 non-null object
17 Unnamed: 17 0 non-null float64
dtypes: float64(1), int64(3), object(14)
memory usage: 400.8+ KB
Selecionando colunas#
As colunas de nosso intersse são: autor da emenda, localidade do gasto e todas as colunas iniciadas por valor. Vamos fazer a seleção através do índice das colunas.
# todas as linhas e as desejadas
df = df.iloc[:, [2,4,11,12,13,14,15,16]]
df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 2849 entries, 0 to 2848
Data columns (total 8 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 Autor da emenda 2849 non-null object
1 Localidade do gasto (Regionalização) 2849 non-null object
2 Valor empenhado 2849 non-null object
3 Valor liquidado 2849 non-null object
4 Valor pago 2849 non-null object
5 Valor Restos a Pagar Inscritos 2849 non-null object
6 Valor Restos a Pagar Cancelados 2849 non-null object
7 Valor Restos a Pagar Pagos 2849 non-null object
dtypes: object(8)
memory usage: 178.2+ KB
Renomeando colunas#
Renomeando as colunas para trabalhar mais facilmente.
# lista com nome das colunas seguindo a ordem do dataframe original
df.columns = ['emenda_autor','local_gasto','vlr_empenhado','vlr_liquido','vlr_pago','vlr_restos_pagar_inscrito'
,'vlr_restos_pagar_cancelados','vlr_restos_pagar_pagos']
df.head()
| emenda_autor | local_gasto | vlr_empenhado | vlr_liquido | vlr_pago | vlr_restos_pagar_inscrito | vlr_restos_pagar_cancelados | vlr_restos_pagar_pagos | |
|---|---|---|---|---|---|---|---|---|
| 0 | MARCIO ALVINO | SÃO PAULO (UF) | 100.000,00 | 0,00 | 0,00 | 100.000,00 | 0,00 | 100.000,00 |
| 1 | JUNIO AMARAL | MINAS GERAIS (UF) | 100.000,00 | 0,00 | 0,00 | 0,00 | 0,00 | 0,00 |
| 2 | JOAQUIM PASSARINHO | PARÁ (UF) | 100.000,00 | 100.000,00 | 100.000,00 | 0,00 | 0,00 | 0,00 |
| 3 | VINICIUS FARAH | PATY DO ALFERES - RJ | 100.000,00 | 0,00 | 0,00 | 100.000,00 | 0,00 | 100.000,00 |
| 4 | SERGIO PETECAO | Nacional | 100.000,00 | 100.000,00 | 100.000,00 | 0,00 | 0,00 | 0,00 |
Convertendo valores#
As colunas de valores hoje estão como texto e precisam ser convertidas para float para que possamos realizar operações matemáticas com elas. O padrão demimal aqui será apenas com ponto como separador pros decimais. Para isto, em cada linha destas serão realizadas duas operações, retirar o ponto como separador de milhar, e substituir a vírgula pelo ponto.
# retira o ponto e depois troca vírgula por ponto
def convert_to_float(x):
return float(x.replace(".","").replace(",","."))
# quero aplicar em todas as colunas que comecem com esse prefixo
prefix = 'vlr_'
# lista das colunas
colunas = [col for col in df if col.startswith(prefix)]
# aplicando a função
for coluna in colunas:
df[coluna] = df[coluna].map(lambda x: convert_to_float(x))
df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 2849 entries, 0 to 2848
Data columns (total 8 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 emenda_autor 2849 non-null object
1 local_gasto 2849 non-null object
2 vlr_empenhado 2849 non-null float64
3 vlr_liquido 2849 non-null float64
4 vlr_pago 2849 non-null float64
5 vlr_restos_pagar_inscrito 2849 non-null float64
6 vlr_restos_pagar_cancelados 2849 non-null float64
7 vlr_restos_pagar_pagos 2849 non-null float64
dtypes: float64(6), object(2)
memory usage: 178.2+ KB
Ajustando valor pago#
Ajustado o valor numérico, precisamos ajustar o valor pago nas emendas.
O pagamento da emeda pode se apresentar nas seguintes formas:
pode ter sido paga, então
vlr_pago > 0evlr_restos_pagar_pagos == 0;pode ter ido para restos a pagar pagos, então
vlr_restos_pagar_pagos > 0evlr_pago == 0;não ter sido paga,
vlr_pago == 0evlr_restos_pagar_pagos == 0.
Estamos interessados nas que foram pagas, ou seja, (vlr_pago > 0 ou vlr_restos_pagar_pagos > 0).
# Criar nova coluna com a soma das colunas
df['vlr'] = df['vlr_pago']+df['vlr_restos_pagar_pagos']
# caso a soma nova coluna for maior que zero
# significa que aquela emenda foi paga
# filtrar apenas estas
df = df[df['vlr']>0]
# selecionar apenas colunas de interesse
df = df[['emenda_autor','local_gasto','vlr']]
df.head()
| emenda_autor | local_gasto | vlr | |
|---|---|---|---|
| 0 | MARCIO ALVINO | SÃO PAULO (UF) | 100000.0 |
| 2 | JOAQUIM PASSARINHO | PARÁ (UF) | 100000.0 |
| 3 | VINICIUS FARAH | PATY DO ALFERES - RJ | 100000.0 |
| 4 | SERGIO PETECAO | Nacional | 100000.0 |
| 6 | EDILAZIO JUNIOR | CODÓ - MA | 100000.0 |
Emendas#
Emendas Estaduais#
Analisando apenas as emendas enviadas apenas para estados, quero saber quantos estados e quantas emendas foram contemplados.
# Separando as emendas estaduais
# Emendas enviadas para estados terminam com (UF)
emendas_estaduais = df.loc[df['local_gasto'].str.contains('(UF)',regex=False), ['local_gasto', 'vlr','emenda_autor']]
# retirando a marcação (UF) do nome do estado.
emendas_estaduais["local_gasto"] = emendas_estaduais["local_gasto"].apply(lambda x: x.replace(" (UF)", ""))
# shape exibe quantidade de linhas e colunas
# quantidade de emendas será a quantidade de linnhas
# para este caso!
emendas_est_qtd = emendas_estaduais.shape[0]
# quantidade de estados que receberam
# assim teremos um array
estados_recebedores = emendas_estaduais['local_gasto'].unique()
estados_emendas_qtd = len(estados_recebedores)
print(f"Quantidade de emendas enviadas para os estados: {emendas_est_qtd}. \
\nQuantidade de estados recebedores de emendas: {estados_emendas_qtd} ")
Quantidade de emendas enviadas para os estados: 1772.
Quantidade de estados recebedores de emendas: 27
Quero saber também as informações do volume financeiro enviado e quantos políticos enviaram para cada estado. Precisamos realizar agregação por estado para somar os valores e contar os autores.
Vou formatar o valor pra ser aprensentado na nossa moeda. Isso tem a desvantagem de transformar a coluna novamente em texto, impedindo operações metemáticas com a coluna. Posteriormente veremos outras formas que preservam o tipo de dado.
# Agrupando os dados para saber quanto foi enviado
emendas_estaduais_agg = (emendas_estaduais.copy().groupby('local_gasto').agg({'local_gasto':'count', 'vlr': 'sum', 'emenda_autor':pd.Series.nunique})
.rename(columns={'local_gasto':'Emendas', 'emenda_autor':'Políticos', 'vlr':'Valor'})
.reset_index())
# renomeando a coluna local_gasto
emendas_estaduais_agg.rename(columns={'local_gasto':'Estado'}, inplace=True)
# formatando o valor
emendas_estaduais_agg["Valor (R$)"] = emendas_estaduais_agg["Valor"].apply(lambda x: format_currency(x, currency="BRL", locale="pt_BR"))
# emendas_estaduais_agg[['Estado','Políticos','Emendas','Valor (R$)']].head()
emendas_estaduais_agg.head()
| Estado | Emendas | Valor | Políticos | Valor (R$) | |
|---|---|---|---|---|---|
| 0 | ACRE | 59 | 2.706689e+08 | 19 | R$ 270.668.887,72 |
| 1 | ALAGOAS | 27 | 2.885476e+08 | 16 | R$ 288.547.617,91 |
| 2 | AMAPÁ | 45 | 3.507016e+08 | 18 | R$ 350.701.642,85 |
| 3 | AMAZONAS | 34 | 2.428814e+08 | 12 | R$ 242.881.420,64 |
| 4 | BAHIA | 148 | 1.075305e+09 | 52 | R$ 1.075.305.291,73 |
Como são muitas linhas, seria melhor ver num gráfico. Vamos criar um treemap para isso.
No gráfico eu gostaria de ver os valores fossem apresentados de forma diferente afim de não coupar muito espaço no gráfico. Por exemplo:
milhares: 1000 = 1K
milhões: 1000000 = 1M
bilhões: 1000000000 = 1B
# apresentar os valores no formato 1K, 1M, 1B
def f(row):
if row['Valor'] >= 10**9:
val = row['Valor']/10**9
val = '{0:.2f}B'.format(val)
elif row['Valor'] >= 10**6 and row['Valor'] < 10**9:
val = row['Valor']/10**6
val = '{0:.2f}M'.format(val)
elif row['Valor'] >= 10**3 and row['Valor'] < 10**6:
val = row['Valor']/10**3
val = '{0:.2f}K'.format(val)
else:
val = '{0:.2f}'.format(row['Valor'])
return val
emendas_estaduais_agg['vlr_prty'] = emendas_estaduais_agg.apply(f, axis=1)
# emendas_estaduais_agg.head()
# treemap com os valores por estado
fig1 = px.treemap(emendas_estaduais_agg, path=[px.Constant("Brasil"), "Estado"], values="Valor", color="Valor", color_continuous_scale='viridis')
fig1.update_traces(
text=emendas_estaduais_agg['vlr_prty'],
textinfo="label+text+percent root", root_color="lightgrey", selector=dict(type='treemap')
,opacity=0.75
)
fig1.show()
Emendas Ceará#
Separando os dados das emendas enviadas para o estado do Ceará e suas cidades.
Neste caso, ao exibir os primeiros valores, gostaria que estivessem formatados, mas sem perder o tipo de dado.
# Dados do estado do ceará e das cidades do ceará
def separar_dados_ce(df):
# emenda direto pro estado do Ceará
df_estado = df.loc[df['local_gasto']=='CEARÁ (UF)']
# emendas para as cidade tem a marcação "- CE"
df_cidades = df.loc[df['local_gasto'].str.contains('- CE')]
# limpando o nome das cidades, retirando a marcação "- CE"
# df_cidades['local_gasto'] = df_cidades["local_gasto"].apply(lambda x: x.replace(" - CE", ""))
# df_ce = pd.concat([df_estados, df_cidades], axis=0)
# df_ce = df_ce[['emenda_autor', 'local_gasto','vlr','vlr_empenhado','vlr_liquido','vlr_pago','vlr_restos_pagar_inscrito','vlr_restos_pagar_cancelados','vlr_restos_pagar_pagos']]
# df_ce = pd.DataFrame(df_ce).sort_values(by=['vlr'], ascending=False)
# return df_ce
return df_estado.reset_index(drop=True), df_cidades.reset_index(drop=True)
df_ce, df_cidades = separar_dados_ce(df)
df_ce = df_ce.sort_values(by='vlr',ascending=False).reset_index(drop=True)
# formatar o valor como moeda, mas presenvando o tipo de dados para que possa fazer cálculos
# adicionar um título na tabela
# df_ce.style \
# .set_caption("Emendas enviadas para o Estado do Ceará") \
# .format(precision=2, thousands=".", decimal=",") \
df_ce.head().style \
.set_caption("Emendas enviadas para o Estado do Ceará") \
.format(precision=2, thousands=".", decimal=",")
| emenda_autor | local_gasto | vlr | |
|---|---|---|---|
| 0 | IDILVAN ALENCAR | CEARÁ (UF) | 16.051.700,00 |
| 1 | ROBERIO MONTEIRO | CEARÁ (UF) | 16.051.699,00 |
| 2 | AJ ALBUQUERQUE | CEARÁ (UF) | 16.051.698,00 |
| 3 | EDUARDO BISMARCK | CEARÁ (UF) | 15.888.779,00 |
| 4 | JUNIOR MANO | CEARÁ (UF) | 15.551.253,00 |
Analisando apenas os dados do estado, vou agrupar os dados por político para ver quantos emendas foram enviadas e o volume por político.
df_ce_agg = (df_ce.copy().groupby('emenda_autor').agg({'emenda_autor':'count', 'vlr': 'sum'})
.rename(columns={'emenda_autor':'Emendas', 'vlr':'Valor'})
.reset_index()
)
df_ce_agg.rename(columns={'emenda_autor':'Autor'}, inplace=True)
df_ce_agg.head()
# print(f"Quantidade de políticos: {df_ce_agg.shape[0]}")
| Autor | Emendas | Valor | |
|---|---|---|---|
| 0 | AJ ALBUQUERQUE | 3 | 35676045.87 |
| 1 | ANDRE FIGUEIREDO | 3 | 24557957.36 |
| 2 | CAPITAO WAGNER | 1 | 7299682.00 |
| 3 | CELIO STUDART | 3 | 34153685.95 |
| 4 | CID GOMES | 1 | 14644231.88 |
Visualizando estas informações numa gráfico de pizza.
fig_autor = px.pie(df_ce_agg, values='Valor', names='Autor', title='Políticos que enviaram emendas')
fig_autor.show()
Cidades Recebedoras#
Para as cidades que receberam emendas, vou retirar a marcação do estado do nome da cidade. Quero ver o nome destas cidades, mas como são muitas, vou distribuí-las em várias colunas de um DataFrame.
# limpando o nome das cidades
df_cidades['local_gasto'] = df_cidades["local_gasto"].apply(lambda x: x.replace(" - CE", ""))
# pegando a lista de cidade sem repetição
def cidades_emendas(df_ce):
locais = sorted(df_ce['local_gasto'].unique())
locais = pd.DataFrame({'cidade':locais})
return locais
# espalhar a lista de cidades num dataframe
def espalhar_cidades(series):
# Create a pandas Series
# Number of columns
n = 5
# Calculate the number of rows needed
num_rows = int(np.ceil(len(series) / n))
# Pad the Series with NaN values if necessary
padded_series = np.pad(series, (0, num_rows * n - len(series)), constant_values='')
# Reshape the Series and convert it to a DataFrame
reshaped_array = padded_series.reshape(num_rows, n)
return pd.DataFrame(reshaped_array)
locais = cidades_emendas(df_cidades)
cidades_qtd = locais.shape[0]
print(f"Quantidade de cidades que receberam emendas {cidades_qtd}")
locais
# quero espalhar esta lista num dataframe para visualizar melhor
df_locais = espalhar_cidades(locais['cidade'])
df_locais
Quantidade de cidades que receberam emendas 49
| 0 | 1 | 2 | 3 | 4 | |
|---|---|---|---|---|---|
| 0 | ACARAÚ | ALCÂNTARAS | ALTANEIRA | AMONTADA | AQUIRAZ |
| 1 | ARATUBA | ASSARÉ | BELA CRUZ | BOA VIAGEM | CARIRIAÇU |
| 2 | CARIRÉ | CHAVAL | CHOROZINHO | CHORÓ | COREAÚ |
| 3 | CRUZ | FORTIM | FRECHEIRINHA | GRANJA | IBIAPINA |
| 4 | IBICUITINGA | ICÓ | IPU | IRACEMA | ITAPIPOCA |
| 5 | ITAREMA | JAGUARIBARA | JAGUARIBE | MARANGUAPE | MILHÃ |
| 6 | MONSENHOR TABOSA | MORADA NOVA | MORAÚJO | MUCAMBO | NOVA RUSSAS |
| 7 | NOVO ORIENTE | PARACURU | PARAIPABA | PARAMBU | PEDRA BRANCA |
| 8 | PENTECOSTE | PIRES FERREIRA | QUITERIANÓPOLIS | RERIUTABA | RUSSAS |
| 9 | SENADOR POMPEU | SÃO BENEDITO | TAMBORIL | URUOCA |
Cidade e valor recebido#
Sobre os valores enviado para cidade, quanto cada cidade recebeu e de quantos políticos diferentes?
cidades_emendas_df = (
df_cidades
.groupby('local_gasto', as_index=False)
.agg({'emenda_autor':pd.Series.nunique, 'vlr': 'sum'})
.reset_index(drop=True)
)
cidades_emendas_df.rename(columns={'local_gasto':'Cidade', 'emenda_autor':'Políticos', 'vlr':'Valor'}, inplace=True)
cidades_emendas_df["Valor (R$)"] = cidades_emendas_df["Valor"].apply(lambda x: format_currency(x, currency="BRL", locale="pt_BR"))
cidades_emendas_df['vlr_prty'] = cidades_emendas_df.apply(f, axis=1)
cidades_emendas_df.head()
| Cidade | Políticos | Valor | Valor (R$) | vlr_prty | |
|---|---|---|---|---|---|
| 0 | ACARAÚ | 1 | 2724347.87 | R$ 2.724.347,87 | 2.72M |
| 1 | ALCÂNTARAS | 1 | 250000.00 | R$ 250.000,00 | 250.00K |
| 2 | ALTANEIRA | 1 | 1000012.00 | R$ 1.000.012,00 | 1.00M |
| 3 | AMONTADA | 1 | 1000000.00 | R$ 1.000.000,00 | 1.00M |
| 4 | AQUIRAZ | 2 | 4672458.52 | R$ 4.672.458,52 | 4.67M |
Criando um treemap para ver melhor.
# fig1 = px.treemap(cidades_emendas_df, path=["Cidade"], values="vlr",color="vlr",color_continuous_scale='viridis')
# fig1.update_traces(
# #textinfo="label+value"
# texttemplate='%{label} <br> %{value: text} <br> %{percentRoot}'
# ,selector=dict(type='treemap')
# )
# fig1.show()
# emendas_estaduais[['Estado','Políticos','Emendas','vlr_prty', 'Valor']]
# cidades_emendas_df.head()
fig2 = px.treemap(cidades_emendas_df, path=[px.Constant("Cidades do Ceará"),"Cidade"], values="Valor", color="Valor", color_continuous_scale='viridis')
fig2.update_traces(
text=cidades_emendas_df['vlr_prty'],
textinfo="label+text",
selector=dict(type='treemap'),
opacity=0.75
)
fig2.show()
Outliers#
Vamos indentificar valores outliers das emendas enviadas para o estado e para as cidades. Os dados não serão agregados e utilizaremos um gráfico boxplot.
# copia dos dados estaduais
df_ce_out = df_ce.copy()
# coluna tipo
df_ce_out['Tipo'] = 'Estadual'
# copia dos dados municipais
df_cidades_out = df_cidades.copy()
# nova coluna tipo
df_cidades_out['Tipo'] = 'Municipal'
df_outliers = pd.concat([df_ce_out,df_cidades_out])
# df_outliers.head()
df_outliers.rename(columns={'vlr':'Valor'}, inplace=True)
fig = px.box(
df_outliers
# , title="Boxplot das emendas estaduais e municipais"
, y="Tipo"
, x="Valor"
, color="Tipo"
)
# fig.update_traces(
# marker=dict(outliercolor='rgb(51, 204, 51)')
# )
fig.update_layout(
title='Boxplot das emendas estaduais e municipais',
yaxis=dict(
# autorange=True,
showgrid=False,
# zeroline=True,
# dtick=5,
# gridcolor='rgb(255, 255, 255)',
# gridwidth=1,
# zerolinecolor='rgb(255, 255, 255)',
# zerolinewidth=2,
title=dict(text="")
# visible=False,
# showticklabels=False
),
xaxis=dict(
# autorange=True,
showgrid=True,
# zeroline=True,
# dtick=5,
gridcolor='rgb(255, 255, 255)',
gridwidth=1,
zerolinecolor='rgb(255, 255, 255)',
zerolinewidth=2,
# visible=False,
# showticklabels=False
),
# margin=dict(
# l=40,
# r=30,
# b=80,
# t=100,
# ),
paper_bgcolor='rgb(243, 243, 243)',
plot_bgcolor='rgb(243, 243, 243)',
showlegend=False
)
fig.show()
Para os dados municipais identificamos alguns outliers. Precisamos identificar quais são estes dados.
def identificar_limites(serie_coluna):
# Calcular os quartis Q1 e Q3
Q1 = serie_coluna.quantile(0.25)
Q3 = serie_coluna.quantile(0.75)
# Calcular o IQR
IQR = Q3 - Q1
# Definir os limites inferior e superior
limite_inferior = Q1 - 1.5 * IQR
limite_superior = Q3 + 1.5 * IQR
return limite_inferior, limite_superior
def get_outliers(df,coluna):
limite_inferior,limite_superior = identificar_limites(df[coluna])
outliers = df[(df[coluna] < limite_inferior) | (df[coluna] > limite_superior)]
return outliers.sort_values(by='Valor', ascending=False)
# return outliers
def get_noutliers(df,coluna):
limite_inferior,limite_superior = identificar_limites(df[coluna])
outliers = df[~((df[coluna] < limite_inferior) | (df[coluna] > limite_superior))]
return outliers.sort_values(by='Valor', ascending=False)
# return outliers
# Identificar outliers
# outliers = df_outliers.query("Tipo == 'Municipal'")
outliers = get_outliers(df_outliers.query("Tipo == 'Municipal'"),'Valor')
# outliers.head()
outliers = outliers[['emenda_autor','local_gasto','Valor']]
outliers = outliers.rename(columns={'emenda_autor':'Político','local_gasto':'Cidade'})
outliers.style \
.set_caption("Dados outliers das emendas pagas para municípios") \
.format(precision=2, thousands=".", decimal=",")
| Político | Cidade | Valor | |
|---|---|---|---|
| 75 | MOSES RODRIGUES | CRUZ | 10.000.000,00 |
| 74 | HEITOR FREIRE | GRANJA | 7.331.441,00 |
| 73 | YURY DO PAREDAO | QUITERIANÓPOLIS | 7.000.000,00 |
| 72 | PEDRO AUGUSTO BEZERRA | NOVO ORIENTE | 6.000.000,00 |
| 71 | GENECIAS NORONHA | PARAMBU | 5.819.682,00 |
| 70 | DR. JAZIEL | NOVO ORIENTE | 5.702.232,00 |
Políticos#
politicos que enviaram
políticos enviaram para quantas cidades diferentes
valor enviado por cada político
politicos_df = (
df_cidades
.groupby(['emenda_autor'], as_index=False)
.agg({'local_gasto':pd.Series.nunique, 'vlr': 'sum'})
)
# politicos_df = politicos_df.sort_values(by='vlr', ascending=False)
politicos_df.rename(columns={'emenda_autor':'Autor', 'local_gasto':'Cidades Recebedoras','vlr':'Valor'}, inplace=True)
politicos_df.style \
.set_caption("Emendas por Político") \
.format(precision=2, thousands=".", decimal=",") \
.background_gradient(subset=["Valor"],cmap="viridis") \
.highlight_max(subset=["Cidades Recebedoras"], color='yellow', axis=0, props=None)
| Autor | Cidades Recebedoras | Valor | |
|---|---|---|---|
| 0 | ANDRE FERNANDES | 4 | 6.847.138,50 |
| 1 | CAPITAO WAGNER | 1 | 1.714.511,00 |
| 2 | CID GOMES | 5 | 3.589.365,00 |
| 3 | DENIS BEZERRA | 2 | 8.447.710,00 |
| 4 | DR. JAZIEL | 6 | 17.205.289,20 |
| 5 | GENECIAS NORONHA | 4 | 8.819.682,00 |
| 6 | HEITOR FREIRE | 2 | 10.997.161,00 |
| 7 | JOSE AIRTON FELIX CIRILO | 1 | 11.258.418,00 |
| 8 | JULIO VENTURA | 4 | 5.475.000,00 |
| 9 | MAURO BENEVIDES FILHO | 5 | 4.300.060,00 |
| 10 | MOSES RODRIGUES | 2 | 10.461.857,04 |
| 11 | PEDRO AUGUSTO BEZERRA | 8 | 14.905.652,00 |
| 12 | ROBERIO MONTEIRO | 13 | 18.924.347,87 |
| 13 | RONALDO MARTINS | 1 | 977.525,00 |
| 14 | VAIDON OLIVEIRA | 5 | 15.640.406,00 |
| 15 | VINICIUS GURGEL | 1 | 2.672.458,52 |
| 16 | YURY DO PAREDAO | 3 | 10.804.665,87 |